

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import Column, Integer, String, Binary, ForeignKey, Boolean, Float, PickleType

from sqlalchemy.orm import relation, backref

from sqlalchemy.schema import UniqueConstraint, Constraint, Table

""" GLOBALS """
DEFAULT_MAX_INDIVIDUALS = 1000
DEFAULT_MAX_PARETO_RANKING = 1

Base = declarative_base()

class Schema(Base):
    __table__ = Table('schema', Base.metadata,
                      Column('id', Integer, primary_key=True),
                      Column('name', String, unique=True, nullable=False),
                      Column('zip_data', Binary, nullable=False),
                      Column('last_modified_time', Float, nullable=False)
                )
    
    populations = relation("PopulationSettings", order_by="PopulationSettings.id", backref="schema")
    
    def __init__(self, name, zip_data, last_modified_time):
        self.name = name
        self.zip_data = zip_data
        self.last_modified_time = last_modified_time
    
    def __repr__(self):
        return "<Schema('%s', '%s', '%s')>" % (self.name, self.last_modified_time)

class PopulationSettings(Base):   
    __table__ = Table('population_settings', Base.metadata,
                      Column('id', Integer, primary_key=True),
                      Column('name', String, nullable=False),
                      Column('max_individuals', Integer),
                      Column('model_name', String),
                      Column('image_name', String),
                      Column('objectives', PickleType),
                      Column('is_stopped', Boolean),
                      Column('schema_id', Integer, ForeignKey('schema.id'), nullable=False),
                      UniqueConstraint('name', 'schema_id')
                )
        
    scripts = relation("ScriptSettings", order_by="ScriptSettings.id", backref="population_settings")
    columns = relation("ColumnSettings", order_by="ColumnSettings.id", backref="population_settings")
    
    def __init__(self, name):
        self.name = name
        self.is_stopped = False
        self.max_individuals = DEFAULT_MAX_INDIVIDUALS
        
    def __repr__(self):
        return "<PopulationSettings('%s', '%s', '%s', '%s')>" %(self.name, self.max_individuals, self.model_name, self.image_name)

class ScriptSettings(Base):    
    __table__ = Table('script_settings', Base.metadata,
                      Column('id', Integer, primary_key=True),
                      Column('name', String, nullable=False),
                      Column('file_name', String, nullable=False),
                      Column('function_name', String, nullable=False),
                      Column('input_size', Integer),
                      Column('cond_select', PickleType),
                      Column('cond_where', PickleType),
                      Column('order_by', PickleType),
                      Column('exclusive_use', Boolean, nullable=False),
                      Column('population_id', Integer, ForeignKey('population_settings.id'), nullable=False)
                )
    
    def __init__(self, name, file_name, function_name):
        self.name = name
        self.file_name = file_name
        self.function_name = function_name
    
    def __init__(self, name, file_name, function_name, input_size=None, cond_select=None, cond_where=None, order_by=None, exclusive_use=True):
        self.name = name
        self.file_name = file_name
        self.function_name = function_name
        self.input_size = input_size
        self.cond_select = cond_select
        self.cond_where = cond_where
        self.order_by = order_by
        self.exclusive_use = exclusive_use
        
    def __repr__(self):
        return "<ScriptSettings('%s', '%s', '%s', '%s')>" %(self.name, self.file_name, self.function_name, self.input_size)

class ColumnSettings(Base):
    __table__ = Table('column_settings', Base.metadata,
                      Column('id', Integer, primary_key=True),
                      Column('column_name', String, nullable=False),
                      Column('column_type', String, nullable=False),
                      Column('population_id', Integer, ForeignKey('population_settings.id'), nullable=False)
                )
    
    def __init__(self, column_name, column_type):
        self.column_name = column_name
        self.column_type = column_type
        
    def __repr__(self):
        return "<ColumnSettings('%s', '%s')>" %(self.column_name, self.column_type)
